<template>
    <div class="popper" @mouseenter="onMouseEnter($event)" @mouseleave="onMouseLeave($event)"
         :class="{ visible: visible }">
        <div class="popper-name">
            <slot></slot>
        </div>
        <div class="popper-content" data-popper-arrow hidden @click="onContentClick($event)">
            <i class="arrow"></i>
            <slot name="pop"></slot>
        </div>
    </div>
</template>
<script>
import { createPopper } from '@popperjs/core';
export default {
    name: "Popper",
    props: {
        option: { type: Object, default: () => { return {} } },
        placement: { type: String, default: 'right' },
        offset: { type: Array, default: null },
        delay: { type: Number },
        closeOnClick: { type: Boolean, default: false },
    },
    data () {
        return {
            instance: null,
            popper: null,
            showTimer: 0,
            hideTimer: 0,
            visible: false,
            defultDelay: { show: 300, hide: 100 },
        };
    },
    methods: {

        // 显示
        onShow () {
            if (this.popover) {
                this.visible = true;
                this.popover.removeAttribute("hidden");
                this.instance.update();
            } else {
                const button = this.$el.querySelector('.popper-name');

                this.visible = true;
                this.popover = this.$el.querySelector('.popper-content');
                this.popover.removeAttribute("hidden");
                this.instance = createPopper(button, this.popover, {
                    placement: this.placement,
                    strategy: 'fixed',
                    modifiers: [
                        {
                            name: 'flip',
                            options: {
                                fallbackPlacements: ['top', 'bottom']
                            }
                        },
                        {
                            name: 'offset',
                            options: {
                                offset: this.offset || [0, 10],
                            },
                        },
                        // {
                        //     name: 'preventOverflow',
                        //     options: { padding: 10 }
                        // }
                    ]
                });
            }
        },

        // 隐藏
        onHide () {
            if (this.popover) {
                this.visible = false;
                this.popover.setAttribute("hidden", "");
            }
        },

        // 鼠标进入
        onMouseEnter (event) {
            const delay = this.getDelay()

            this.showTimer && clearTimeout(this.showTimer);
            this.hideTimer && clearTimeout(this.hideTimer);
            this.showTimer = setTimeout(() => {
                this.showTimer = 0;
                this.onShow();
            }, delay.show);

        },
        // 鼠标离开
        onMouseLeave (event) {
            const delay = this.getDelay()

            if (this.showTimer) {
                clearTimeout(this.showTimer);
                this.onHide();
            } else if (this.visible) {
                this.hideTimer && clearTimeout(this.hideTimer);
                this.hideTimer = setTimeout(this.onHide, delay.hide);
            }
        },

        // 获取延时时间
        getDelay () {
            if (Number.isFinite(this.delay)) {
                return {
                    show: this.delay,
                    hide: this.delay,
                }
            } else if (this.delay) {
                return Object.assign({ ...this.defultDelay }, this.delay)
            } else {
                return this.defultDelay
            }
        },

        onContentClick () {
            this.closeOnClick && this.onHide()
        }
    },
    beforeDestroy () {
        this.instance && this.instance.destroy();
        this.showTimer && clearTimeout(this.showTimer);
        this.hideTimer && clearTimeout(this.hideTimer);
        this.instance = null;
        this.popover = null;
    }
};
</script>
<style lang="scss" scoped>
.popper {
    position: relative;
}

.popper-name {
    cursor: default;
}

.popper-content {
    box-sizing: border-box;
    font-size: 0;
    position: fixed;
    box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
    border: 1px solid #ebeef5;
    border-radius: 6px;
    background: #fff;
    white-space: normal;
    text-align: left;
    left: 100%;
    visibility: visible;
    z-index: 99;

    .arrow {
        position: absolute;
        top: 50%;
        left: 50%;
        width: 0;
        height: 0;

        &::before {
            position: absolute;
            width: 8px;
            height: 8px;
            box-sizing: border-box;
            top: 50%;
            left: 50%;
            background: #fff;
            visibility: visible;
            content: '';
            transform: rotate(45deg);
            margin-left: -4px;
            margin-top: -4px;
        }
    }

    &[data-popper-placement^='top'] .arrow {
        bottom: 0;
        margin-top: auto;
        top: auto;

        &::before {
            border-right: 1px solid #ebeef5;
            border-bottom: 1px solid #ebeef5;
        }
    }

    &[data-popper-placement^='bottom'] .arrow {
        top: 0;

        &::before {
            border-left: 1px solid #ebeef5;
            border-top: 1px solid #ebeef5;
        }
    }

    &[data-popper-placement^='left'] .arrow {
        right: 0;
        left: auto;
    }

    &[data-popper-placement^='right'] .arrow {
        left: 0;

        &::before {
            border-left: 1px solid #ebeef5;
            border-bottom: 1px solid #ebeef5;
        }
    }

    &[hidden] {
        visibility: hidden;
        display: none !important;
    }
}
</style>
